
// ===============================================================================================================
// -*- FRAGMENT SHADER -*-
//
// Fire.frag - GLSL fragment shader for a billboarded fire effect.
//
// Copyright (c) 2011 Guilherme R. Lampert
// guilherme.ronaldo.lampert@gmail.com
//
// This code is licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// above is included in the resulting source code.
//
// ===============================================================================================================

uniform float distortionAmount0;
uniform float distortionAmount1;
uniform float distortionAmount2;

uniform float heightAttenuationX;
uniform float heightAttenuationY;

uniform sampler2D fireDistortion;
uniform sampler2D fireOpacity;
uniform sampler2D fireBase;

varying vec2 vTexCoord0;
varying vec2 vTexCoord1;
varying vec2 vTexCoord2;
varying vec2 vTexCoord3;

// Bias and double a value to take it from 0..1 range to -1..1 range
vec4 bx2v(vec4 x)
{
	vec4 retVal = vec4((2.0 * x) - 1.0);
	return (retVal);
}

void main(void)
{
	// Sample noise map three times with different texture coordinates
	vec4 noiseV0 = texture2D(fireDistortion, vTexCoord1);
	vec4 noiseV1 = texture2D(fireDistortion, vTexCoord2);
	vec4 noiseV2 = texture2D(fireDistortion, vTexCoord3);

	// Weighted sum of signed noise
	vec4 noiseSum = bx2v(noiseV0) * distortionAmount0 + 
					bx2v(noiseV1) * distortionAmount1 + 
					bx2v(noiseV2) * distortionAmount2;

	// Perturb base coordinates in direction of noiseSum as function of height (y)
	vec2 perturbedBaseCoords = vTexCoord0 + noiseSum.xy * (vTexCoord0.y * (heightAttenuationX + heightAttenuationY));

	// Sample base and opacity maps with perturbed coordinates
	vec4 base    = texture2D(fireBase,    perturbedBaseCoords);
	vec4 opacity = texture2D(fireOpacity, perturbedBaseCoords);

	gl_FragColor = base * opacity;
}